#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2025 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import logging
import os
import json
import re
from utils import utils_data, ErrorInfoBuilder

logger = logging.getLogger('my_logger')


def extract_testsuite(file_content, file_path):
    testsuite_regex = re.compile(r'describe\s*\(\s*["\'](.*?)["\']', re.MULTILINE)
    testsuites = {}
    duplicates = []
    lines = file_content.splitlines()

    for i, line in enumerate(lines):
        match = testsuite_regex.search(line)
        if match:
            testsuite_name = match.group(1)
            if testsuite_name in testsuites:
                duplicates.append({
                    "file_path": file_path,
                    "testsuite": testsuite_name,
                    "line_num": i + 1,
                    "code_line": line.strip()
                })
            else:
                testsuites[testsuite_name] = (i + 1, line.strip())

    return testsuites, duplicates


def read_file_content(file_path):
    with open(file_path, 'r', encoding='utf-8') as f:
        return f.read()


def check_for_duplicates_in_directory(directory, current_file_path, current_file_testsuites):
    all_testsuites = set()
    duplicates = []

    for root, _, files in os.walk(directory):
        for file in files:
            if file.endswith(('.test.ets', '.test.js')):
                file_path = os.path.join(root, file)

                if file_path == current_file_path:
                    continue

                file_content = read_file_content(file_path)
                testsuites, file_duplicates = extract_testsuite(file_content, file_path)
                duplicates.extend(file_duplicates)

                for testsuite in testsuites:
                    if testsuite in all_testsuites:
                        if testsuite in current_file_testsuites:
                            duplicate_info = {
                                "file_path": current_file_path,
                                "testsuite": testsuite,
                                "line_num": current_file_testsuites[testsuite][0],
                                "code_line": current_file_testsuites[testsuite][1]
                            }
                            if duplicate_info not in duplicates:
                                duplicates.append(duplicate_info)
                    else:
                        all_testsuites.add(testsuite)

    return duplicates


def check_testsuite():
    file_entities = utils_data.get_file()
    recorded_errors = {}
    has_error = False

    for file_entity in file_entities:
        if file_entity.file_name.endswith(('.test.ets', '.test.js')):
            file_content = read_file_content(file_entity.full_path)
            testsuites, file_duplicates = extract_testsuite(file_content, file_entity.full_path)
            language = "arkts" if file_entity.file_name.endswith('.test.ets') else "javascript"

            for duplicate in file_duplicates:
                error_key = (file_entity.full_path, duplicate["testsuite"])
                if error_key not in recorded_errors or duplicate["line_num"] > recorded_errors[error_key]:
                    recorded_errors[error_key] = duplicate["line_num"]

                    error_info = ErrorInfoBuilder() \
                        .set_buggy_file_path(file_entity.file_path) \
                        .set_defect_type("XTS.CHECK.TESTSUITE.01") \
                        .set_description("测试组件testsuite在同一个测试工程中命名不能重复") \
                        .set_main_buggy_line(duplicate["line_num"]) \
                        .set_main_buggy_code(duplicate["code_line"]) \
                        .set_language(language) \
                        .build()

                    utils_data.write_error_to_json_file(error_info)
                    logger.info(json.dumps(error_info, indent=4, ensure_ascii=False))
                    has_error = True

            parent_directory = os.path.dirname(file_entity.full_path)
            duplicates = check_for_duplicates_in_directory(parent_directory, file_entity.full_path, testsuites)

            for duplicate in duplicates:
                error_key = (file_entity.full_path, duplicate["testsuite"])
                if error_key not in recorded_errors or duplicate["line_num"] > recorded_errors[error_key]:
                    recorded_errors[error_key] = duplicate["line_num"]

                    error_info = ErrorInfoBuilder() \
                        .set_buggy_file_path(file_entity.file_path) \
                        .set_defect_type("XTS.CHECK.TESTSUITE.01") \
                        .set_description("测试组件testsuite在同一个测试工程中命名不能重复") \
                        .set_main_buggy_line(duplicate["line_num"]) \
                        .set_main_buggy_code(duplicate["code_line"]) \
                        .set_language(language) \
                        .build()

                    utils_data.write_error_to_json_file(error_info)
                    logger.info(json.dumps(error_info, indent=4, ensure_ascii=False))
                    has_error = True

    if has_error:
        logger.info("测试组件testsuite命名重复问题检查完成，错误信息已写入xts_result.json")
    else:
        logger.info("测试组件testsuite命名重复问题检查通过")